#include "DataMan.h"
#include <QFile>
#include <QDebug>
#include <QCryptographicHash>
#include <qquickitem.h>
#define NOW_VERSION		1
#define DATA_MAGIC		0x43F0BA92
#define DATA_FILE_PATH		"data"

QVariantList DataMan::garr() const
{
	QVariantList r;
	r.reserve(sizeof(d.garr));
	for (uint i = 0;i < sizeof(d.garr); ++i)
		r.append(d.garr[i]);
	return r;
}

void DataMan::setgarr(const QVariantList& in)
{
	int i = 0;
	for (QVariantList::const_iterator it = in.begin(); it != in.end(); ++it) {
		d.garr[i] = (int8_t)(it->toInt());
		++i;
	}
}

QVariantList DataMan::propN() const
{
	QVariantList r;
	r.reserve(PropTypeN);
	for (int i = 0;i < PropTypeN; ++i)
		r.append(d.propN[i]);
	return r;
}

void DataMan::setpropN(const QVariantList& in)
{
	int i = 0;
	for (QVariantList::const_iterator it = in.begin(); it != in.end(); ++it) {
		d.propN[i] = (uint)it->toInt();
		++i;
	}
}

DataMan*DataMan::instance()
{
	static DataMan* r = NULL;
	if (!r)
		r = new DataMan();
	return r;
}

void DataMan::load()
{
	QFile fp(DATA_FILE_PATH);
	if (fp.exists()) {
		if (!fp.open(QFile::ReadOnly)) {
			qWarning() << "打开配置文件失败";
			goto do_err;
		}
		if (fp.size() != sizeof(struct Data)) {
			qWarning() << "验证配置文件失败";
			goto do_err;
		}
		if (sizeof(struct Data) != fp.read((char*)&d, sizeof(struct Data))) {
			qWarning() << "读取配置文件失败";
			goto do_err;
		}
		if (d.magic != DATA_MAGIC) {
			qWarning() << "配置文件不是标准的游戏配置文件";
			goto do_err;
		}
		if (d.version != NOW_VERSION) {
			qWarning() << "配置文件版本与当前使用版本不相符";
			goto do_err;
		}
		fp.close();
		m_hash = QCryptographicHash::hash(QByteArray((const char*)&d, sizeof(d)), QCryptographicHash::Md5);
		return;
	} else {
		reset(true);
		return;
	}
do_err:
	fp.close();
	reset(true);
}

bool DataMan::save()
{
	QByteArray hash = QCryptographicHash::hash(QByteArray((const char*)&d, sizeof(d)), QCryptographicHash::Md5);
	if (hash == m_hash)  return true;
	QFile fp(DATA_FILE_PATH);
	if (!fp.open(QFile::WriteOnly)) {
		qWarning() << "写入配置时，打开文件失败";
		return false;
	}
	bool r = true;
	if (sizeof(d) != fp.write((const char*)&d, sizeof(d))) {
		qWarning() << "写入配置文件失败";
		r = false;
	}
	fp.close();
	return r;
}

DataMan::DataMan()
{  }

void DataMan::reset(bool first)
{
	qDebug() << "重置配置文件";
	if (first) {
		memset(&d, 0, sizeof(d));
		d.music = true;
		d.version = NOW_VERSION;
		d.magic	= DATA_MAGIC;
	}
	d.firstPlay = first;
	d.lv = 1;
	d.nowSc = 0;
	d.propN[PDSc] = 2;
	d.propN[PHar] = 5;
	d.propN[PRe] = 2;
	d.propN[PHeart] = 2;
	d.propN[PZom] = 4;
	m_hash = QCryptographicHash::hash(QByteArray((const char*)&d, sizeof(d)), QCryptographicHash::Md5);
}
